// http://openjsan.org/doc/a/ad/adamk/Upgrade/0.04/lib/Upgrade.html
if (!Array.prototype.push) {
	Array.prototype.push = function() {
		for( var i=0; i<arguments.length; i+=1 ) {
			this[this.length] = arguments[i];
		}
		return this.length;
	}
}



function CookieKeeper(cookieName,dontCookieFalseValues,cookieExpires,cookiePath,cookieDomain,cookieSecure,maxCookies) {
//	this.c = [];
	this.c = {};
	
	this.init = function(cookieName,dontCookieFalseValues,cookieExpires,cookiePath,cookieDomain,cookieSecure,maxCookies) {
		this.cName = cookieName || 'default';
		this.dcfv = dontCookieFalseValues;
		
		this.setExpires(cookieExpires);
		this.setPath(cookiePath);
		this.setSecure(cookieDomain);
		this.setSecure(cookieSecure);
		this.setMaxCookies(maxCookies);
	};
	
	
	
	this.setMaxCookies = function(m) {
		if ( typeof(m) != 'undefined' && m !=== null ) {
			this.maxCookies = m;
		}
		else {
			this.maxCookies = 19;
		}
	};
	this.getMaxCookies = function() { return this.maxCookies; };
	
	
	
	this.setExpires = function(ex) {
		var dt = new Date( ex );
		if ( 'Invalid Date' == dt ) { dt = new Date(0); }
		this.expires = dt.toGMTString();
		return this.expires;
	};
	this.getExpires = function() { return this.expires; };
	this.setExpiresAtOneYear = function() {
		var td = new Date(); // today
		this.setExpires( new Date( td.getFullYear()+1, td.getMonth(), td.getDate(), td.getHours(), td.getMinutes() ) );
		return this.expires;
	};
	
	
	
	this.setPath = function(p) {
		if ( typeof(p) != 'undefined' && p !=== null ) {
			this.cPath = p;
		}
		else {
			this.cPath = '/'; // granted, not the rfc default, but this seems to be the more useful default
		}
	};
	this.getPath = function() { return this.cPath; };
	
	
	
	this.setDomain = function(d) { this.cDomain = d; };
	this.getDomain = function() { return this.cDomain; };
	
	
	
	this.setSecure = function(b) { this.cSecure = !!(b); };
	this.getSecure = function() { return this.cSecure; };
	
	
	
	this.setParameter = function(k,v) { this.c[k] = v; };
	this.getParameter = function(k) { return this.c[k]; };
	
	this.doesPropertyExist = function(k) {
		return (typeof( this.c[k] ) != 'undefined' && this.c[k] !== null);
	};
	
	
	
	this.getCookie = function(n) {
		n = n || this.cName;
		var re = new RegExp( '^' + n + '[0-9]{1,2}$' );
		var ary = [];
		var o = ''; // o = output string
//		for ( var i=0, s = document.cookie.split(';'); i<s.length; i+=1 ) {
		for ( var i=0, s = document.cookie.split(/;\s*/); i<s.length; i+=1 ) {
			var c = s[i].split(/\s*=\s*/); // c = cookie
			var p = unescape(c[0]); // p = parameter
			if ( p.search(re) != -1 ) {
				var v = ''; // v = cookie value
				// just to make sure we get a cookie that is 'foo=bar=baz'
				for ( var j=1; j<c.length; j+=1 ) {
					v += '=' + c[j];
				}
//				c[1] = v.replace( /^\=/, '' );
//				return unescape(c[1]);
				ary[p] = v.replace( /^\=/, '' );
			}
		}
//		if ( ary.length ) {
			for ( var i=0; i<19; i+=1 ) { // forced 19 because max is 20 - 1 session cookie
				if ( ary[n+''+i] ) {
					o += ary[n+''+i];
				}
			}
//		}
		if ( o ) {
			return unescape(o);
		}
		else {
			return null;
		}
	};
	
	
	
	this.setCookie = function()
	{
		var c = '=' + escape(this.toJSONString());
		var extra = '; expires=' + this.cExpires
			+ ((this.getPath) ? '; path=' + this.getPath : '')
			+ ((this.cDomain) ? '; domain=' + this.cDomain : '')
			+ ((this.cSecure) ? '; secure' : '')
		;
		this.checkSize(this.cName,c,extra);
		document.cookie = this.cName + c + extra;
	};
	
	
	
	
	this.parseJSON = function(s) {
		s = s || this.getCookie();
		try {
			re = new RegExp( '^("(\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$' );
			if ( re.test(s) ) {
//				alert( 's = ' + s );
				var j = eval('(' + s + ')');
				return j;
			}
		}
		catch (e) {}
		throw new SyntaxError("parseJSON");
	};
	
	
	
	
	this.toJSONString = function() {
		var o = ['{'];
		var b;
		
		function p(s) {
			if(b) {
				o[o.length] = ',';
			}
			o[o.length] = s;
			b = true;
		}
		
		for ( var i in this.c ) {
			if ( this.c.hasOwnProperty(i) ) {
				if ( this.dcfv && this.c[i] === false ) {}
				else {
						p( this._jsonStringify( i, this.collection[i] ) );
				}
			}
		}
		o[o.length] = '}';
		return o.join('');
	};
	
	
	
	
	/* private method used by this.toJSONString() */
	this._jsonStringify = function(k,v) {
		var o = '';
		if (v !== null) {
			if(k) {
				o = '"' + k + '":';
			}
			if( v.toJSONString ) {
				o += '"' + v.toJSONString() + '"';
			}
			else if( typeof(v) == 'boolean' ) {
				o += (v?'true':'false');
			}
			else {
				o += '"' + v + '"';
			}
		}
		return o;
	};
	
	
	
	
	/* initialize the object */
	this.init(cookieName,dontCookieFalseValues,cookieExpires,cookiePath,cookieDomain,cookieSecure);
}


